package com.sinosoft.dsp.persistence.businessconcept.facade;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.faces.bean.ManagedProperty;

import org.hibernate.Query;
import org.hibernate.Session;
import org.w3c.dom.Node;

import com.sinosoft.builder.config.BusinessConceptHelper;
import com.sinosoft.builder.utils.BusinessConceptTableType;
import com.sinosoft.dsp.persistence.businessconcept.IBusinessConceptDomainContentEntity;
import com.sinosoft.dsp.persistence.businessconcept.IBusinessConceptDomainEntity;
import com.sinosoft.dsp.persistence.exception.SinoPersistenceException;
import com.sinosoft.dsp.system.core.log.Log;
import com.sinosoft.dsp.platform.services.BussinessConceptService;
import com.sinosoft.dsp.system.core.exception.SinoXMLException;
import com.sinosoft.dsp.system.utils.Const;
import com.sinosoft.dsp.system.utils.ReflectionUtils;
import com.sinosoft.dsp.system.utils.UUIDUtil;

/**
 * 领域对象门面
 * 
 * @author 潘巍（Peter Pan）
 * @since 2010-11-12 下午06:44:45
 */
public class DomainFacade implements IDomainFacade {

	private static final Log log = Log.getLog(DomainFacade.class.getName());

	@ManagedProperty(value = "#{bussinessConceptService}")
	BussinessConceptService bc;

	Session session;

	// ID
	private String id;

	// 领域概念id
	private String conceptId;

	// 领域概况描述
	private String description;

	// 当前领域状态
	private String currentStatus;

	// 当前领域状态开始时间
	private Date currentStatusBeginTime;

	// 当前领域状态结束时间
	private Date currentStatusEndTime;

	// 保密级别
	private String secretLevel;

	private String currentTimestamp;

	// 实体内容数据
	private List<IBusinessConceptDomainContentEntity<?>> contents = new ArrayList<IBusinessConceptDomainContentEntity<?>>();

	// 实体内容的ID和内容数据对象的Map
	private Map<String, IBusinessConceptDomainContentEntity<?>> dataMapById = new HashMap<String, IBusinessConceptDomainContentEntity<?>>();

	public void setSession(Session session) {
		this.session = session;
	}

	@Override
	public String getId() {
		return id;
	}

	@Override
	public void setId(String id) {
		this.id = id;
	}

	@Override
	public String getConceptId() {
		return conceptId;
	}

	@Override
	public void setConceptId(String conceptId) {
		this.conceptId = conceptId;
	}

	@Override
	public String getDescription() {
		return description;
	}

	@Override
	public void setDescription(String description) {
		this.description = description;
	}

	@Override
	public String getCurrentStatus() {
		return currentStatus;
	}

	@Override
	public void setCurrentStatus(String currentStatus) {
		this.currentStatus = currentStatus;
	}

	@Override
	public Date getCurrentStatusBeginTime() {
		return currentStatusBeginTime;
	}

	@Override
	public void setCurrentStatusBeginTime(Date currentStatusBeginTime) {
		this.currentStatusBeginTime = currentStatusBeginTime;
	}

	@Override
	public Date getCurrentStatusEndTime() {
		return currentStatusEndTime;
	}

	@Override
	public void setCurrentStatusEndTime(Date currentStatusEndTime) {
		this.currentStatusEndTime = currentStatusEndTime;
	}

	@Override
	public String getSecretLevel() {
		return secretLevel;
	}

	@Override
	public void setSecretLevel(String secretLevel) {
		this.secretLevel = secretLevel;
	}

	/**
	 * 添加领域内容
	 * 
	 * @param attr
	 */
	@Override
	public void addContent(IBusinessConceptDomainContentEntity<?> attr) {
		attr.setId(UUIDUtil.getUUIDAsString());
		contents.add(attr);
		dataMapById.put(attr.getId(), attr);
	}

	@Override
	public String create() throws SinoPersistenceException {
		try {
			// 创建领域
			createDomainEntity();

			// 重新设置复合领域内容
			resetComplexDomainContentEntity();

			// 创建领域内容
			for (IBusinessConceptDomainContentEntity<?> ccae : contents) {
				createDomainContentEntity(ccae);
			}
			return id;
		} catch (Exception e) {
			throw new SinoPersistenceException("用户自定义事务出现错误");
		}
	}

	/**
	 * 重新设置复合内容<br>
	 * 如果复合概念存在使用原有的，<br>
	 * 如果复合概念关联的内容不存在删除，<br>
	 * 如果不存在复合概念创建
	 */
	private void resetComplexDomainContentEntity() {
		// TODO
	}

	/**
	 * 重新设置领域实体
	 * 
	 * @param de
	 */
	private void resetDomainEntity(IBusinessConceptDomainEntity de) {
		// TODO
	}

	private void createDomainContentEntity(
			IBusinessConceptDomainContentEntity<?> cdce) {
		// 保存内容属性
		cdce.setId(UUIDUtil.getUUIDAsString());
		cdce.createNewTimestamp();
		session.save(cdce);
	}

	private void mergeEntityContentConcept(
			IBusinessConceptDomainContentEntity<?> cdce) {
		if (cdce.checkUpdate()) {
			cdce.createNewTimestamp();
			session.merge(cdce);
		}
	}

	private void createDomainEntity() throws SinoPersistenceException {
		try {
			IBusinessConceptDomainEntity de = (IBusinessConceptDomainEntity) ReflectionUtils
					.newInstance(BusinessConceptHelper
							.getBusinessConceptTableClass(BusinessConceptTableType.DOMAIN));
			this.id = UUIDUtil.getUUIDAsString();
			resetDomainEntity(de);
			de.createNewTimestamp();
			session.save(de);
		} catch (Exception e) {
			log.error("创建领域实体出现错误");
			throw new SinoPersistenceException("创建领域实体出现错误");
		}
	}

	private void mergeDomainEntity() throws SinoPersistenceException {
		try {
			IBusinessConceptDomainEntity de = (IBusinessConceptDomainEntity) session
					.get(
							BusinessConceptHelper
									.getBusinessConceptTableClass(BusinessConceptTableType.DOMAIN),
							id);
			if (!de.getTimestamp().equals(currentTimestamp)) {
				throw new SinoPersistenceException("领域实体修改发生脏读数据，ID：" + id);
			}
			resetDomainEntity(de);
			if (de.checkUpdate()) {
				de.createNewTimestamp();
				session.merge(de);
			}
		} catch (SinoPersistenceException e) {
			log.error(e.getMessage());
			throw e;
		} catch (Exception e) {
			log.error("修改领域实体出现错误，ID：" + id);
			throw new SinoPersistenceException("修改领域实体出现错误，ID：" + id);
		}
	}

	@Override
	public boolean merge() throws SinoPersistenceException {
		try {
			// 如果ID为空，创建实体
			if (Const.isEmpty(id))
				createDomainEntity();
			else
				mergeDomainEntity();

			// 更新或创建实体内容
			for (IBusinessConceptDomainContentEntity<?> cdce : contents) {
				if (Const.isEmpty(cdce.getId()))
					createDomainContentEntity(cdce);
				else
					mergeEntityContentConcept(cdce);
			}
			return true;
		} catch (Exception e) {
			throw new SinoPersistenceException("用户自定义事务出现错误");
		}
	}

	@Override
	public boolean remove() throws SinoPersistenceException {
		try {
			// 如果ID为不为空
			if (!Const.isEmpty(id)) {
				session
						.delete(session
								.get(
										BusinessConceptHelper
												.getBusinessConceptTableClass(BusinessConceptTableType.DOMAIN),
										id));

				// 删除实体内容
				session
						.createQuery(
								"delete from "
										+ BusinessConceptHelper
												.getBusinessConceptTableClassName(BusinessConceptTableType.DOMAIN_CONTENT)
										+ " t where t.domainId='" + id + "'")
						.executeUpdate();
				session
						.createQuery(
								"delete from "
										+ BusinessConceptHelper
												.getBusinessConceptTableClassName(BusinessConceptTableType.DOMAIN_CONTENT_NO_INDEX)
										+ " t where t.domainId='" + id + "'")
						.executeUpdate();
			}
			return true;
		} catch (Exception e) {
			log.error("移除领域实体时出现错误", e);
			throw new SinoPersistenceException("移除领域实体时出现错误");
		}
	}

	@SuppressWarnings("unchecked")
	@Override
	public void instantiate(String id) throws SinoPersistenceException {

		try {
			Query query = session
					.createQuery("select t from "
							+ BusinessConceptHelper
									.getBusinessConceptTableClassName(BusinessConceptTableType.DOMAIN)
							+ " t where t.domainId='" + id + "'");
			IBusinessConceptDomainEntity domain = (IBusinessConceptDomainEntity) query
					.uniqueResult();
			// TODO
			query = session
					.createQuery("select t from "
							+ BusinessConceptHelper
									.getBusinessConceptTableClassName(BusinessConceptTableType.DOMAIN_CONTENT)
							+ " t where t.domainId='" + id + "'");
			List<IBusinessConceptDomainContentEntity<?>> contents = query
					.list();
			if (contents != null && contents.size() > 0) {
				for (IBusinessConceptDomainContentEntity<?> cont : contents) {
					addContent(cont);
				}
			}

			query = session
					.createQuery("select t from "
							+ BusinessConceptHelper
									.getBusinessConceptTableClassName(BusinessConceptTableType.DOMAIN_CONTENT_NO_INDEX)
							+ " t where t.domainId='" + id + "'");
			contents = query.list();
			if (contents != null && contents.size() > 0) {
				for (IBusinessConceptDomainContentEntity<?> cont : contents) {
					addContent(cont);
				}
			}
		} catch (Exception e) {
			throw new SinoPersistenceException("初始化领域实体出现错误，领域实体ID：" + id);
		}
	}

	@Override
	public String getXML() throws SinoXMLException {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public void instantiateFromNode(Node node) throws SinoXMLException {
		// TODO Auto-generated method stub
	}

}
